/**
 * 市场数据服务
 * 管理股票价格、历史数据、价格波动算法
 */

import { getGameTimeEngine } from "./GameTime";

export interface StockQuote {
  symbol: string;
  name: string;
  lastPrice: number;
  openPrice: number;
  highPrice: number;
  lowPrice: number;
  volume: number;
  change: number;
  changePercent: number;
  timestamp: Date;
}

export interface PriceHistoryPoint {
  timestamp: Date;
  price: number;
  volume: number;
}

/**
 * 股票基础信息
 */
interface StockInfo {
  symbol: string;
  name: string;
  sector: string;
  basePrice: number; // 基准价格
  volatility: number; // 波动率 (0-1)
  trend: number; // 趋势 (-1 到 1，-1为下跌趋势，1为上涨趋势)
}

/**
 * 简化的市场数据生成器
 */
export class MarketDataService {
  private stocks: Map<string, StockInfo> = new Map();
  private quotes: Map<string, StockQuote> = new Map();
  private history: Map<string, PriceHistoryPoint[]> = new Map();

  constructor() {
    this.initializeStocks();
  }

  /**
   * 初始化股票列表
   */
  private initializeStocks(): void {
    const stockList: StockInfo[] = [
      {
        symbol: "TT-BANK",
        name: "大亨银行",
        sector: "金融",
        basePrice: 20.0,
        volatility: 0.02, // 2% 波动率
        trend: 0.05, // 轻微上涨趋势
      },
      {
        symbol: "TT-TECH",
        name: "大亨科技",
        sector: "科技",
        basePrice: 85.0,
        volatility: 0.04, // 4% 波动率（科技股更波动）
        trend: 0.1, // 较强上涨趋势
      },
      {
        symbol: "TT-SHIPPING",
        name: "大亨航运",
        sector: "物流",
        basePrice: 12.0,
        volatility: 0.015, // 1.5% 波动率
        trend: -0.02, // 轻微下跌趋势
      },
      {
        symbol: "TT-ENERGY",
        name: "大亨能源",
        sector: "能源",
        basePrice: 65.0,
        volatility: 0.025,
        trend: 0.03,
      },
      {
        symbol: "TT-LUX",
        name: "大亨奢品",
        sector: "消费",
        basePrice: 150.0,
        volatility: 0.03,
        trend: 0.08,
      },
      {
        symbol: "TT-LOGI",
        name: "大亨物流",
        sector: "物流",
        basePrice: 35.0,
        volatility: 0.02,
        trend: 0.04,
      },
    ];

    for (const stock of stockList) {
      this.stocks.set(stock.symbol, stock);
      // 初始化价格
      const initialQuote: StockQuote = {
        symbol: stock.symbol,
        name: stock.name,
        lastPrice: stock.basePrice,
        openPrice: stock.basePrice,
        highPrice: stock.basePrice,
        lowPrice: stock.basePrice,
        volume: 0,
        change: 0,
        changePercent: 0,
        timestamp: new Date(),
      };
      this.quotes.set(stock.symbol, initialQuote);
      this.history.set(stock.symbol, []);
    }
  }

  /**
   * 获取所有股票行情
   */
  getAllQuotes(): StockQuote[] {
    this.updateAllPrices();
    return Array.from(this.quotes.values());
  }

  /**
   * 获取指定股票的行情
   */
  getQuote(symbol: string): StockQuote | null {
    this.updatePrice(symbol);
    return this.quotes.get(symbol) ?? null;
  }

  /**
   * 获取价格历史（最近N个点）
   */
  getPriceHistory(symbol: string, limit: number = 100): PriceHistoryPoint[] {
    const history = this.history.get(symbol) ?? [];
    return history.slice(-limit);
  }

  /**
   * 添加新的股票
   */
  addStock(stock: StockInfo): void {
    this.stocks.set(stock.symbol, stock);
    const initialQuote: StockQuote = {
      symbol: stock.symbol,
      name: stock.name,
      lastPrice: stock.basePrice,
      openPrice: stock.basePrice,
      highPrice: stock.basePrice,
      lowPrice: stock.basePrice,
      volume: 0,
      change: 0,
      changePercent: 0,
      timestamp: new Date(),
    };
    this.quotes.set(stock.symbol, initialQuote);
    this.history.set(stock.symbol, []);
  }

  /**
   * 更新所有股票价格
   */
  private updateAllPrices(): void {
    for (const symbol of this.stocks.keys()) {
      this.updatePrice(symbol);
    }
  }

  /**
   * 更新单个股票价格（使用随机游走 + 趋势模型）
   */
  private updatePrice(symbol: string): void {
    const stock = this.stocks.get(symbol);
    const quote = this.quotes.get(symbol);
    if (!stock || !quote) {
      return;
    }

    const gameTime = getGameTimeEngine();
    const isTrading = gameTime.isTradingHours();

    // 非交易时间价格不变
    if (!isTrading) {
      return;
    }

    // 获取当前游戏时间
    const gameDate = gameTime.getGameDate();
    const gameNow = gameDate.getTime();
    
    // 计算游戏时间流逝（秒）
    const timeDelta = (gameNow - quote.timestamp.getTime()) / 1000;

    // 如果游戏时间流逝很少，不更新（至少需要1秒游戏时间）
    if (timeDelta < 1) {
      return;
    }

    // 随机游走：dS = S * (mu * dt + sigma * sqrt(dt) * random)
    // 简化版：基于波动率和趋势
    const dt = Math.min(timeDelta / 3600, 1); // 归一化到小时

    // 趋势项
    const trendTerm = stock.trend * dt;

    // 随机项（正态分布近似）
    const randomTerm =
      stock.volatility *
      Math.sqrt(dt) *
      (Math.random() * 2 - 1) *
      (0.5 + Math.random() * 0.5); // 偏向当前价格

    // 价格变化百分比
    const changePercent = trendTerm + randomTerm;

    // 计算新价格
    const newPrice = quote.lastPrice * (1 + changePercent);
    
    // 涨停跌停限制：基于开盘价的 ±10%
    const limitUpPrice = quote.openPrice * 1.10; // 涨停价
    const limitDownPrice = quote.openPrice * 0.90; // 跌停价
    
    // 应用涨停跌停限制
    const clampedPrice = Math.max(limitDownPrice, Math.min(limitUpPrice, newPrice));
    const finalPrice = Math.max(0.01, clampedPrice); // 价格不能为负

    // 更新成交量（随机）
    const volumeChange = Math.floor(Math.random() * 10000);

    // 更新行情（使用游戏时间）
    const updatedQuote: StockQuote = {
      ...quote,
      lastPrice: Number(finalPrice.toFixed(2)),
      highPrice: Math.max(quote.highPrice, finalPrice),
      lowPrice: Math.min(quote.lowPrice, finalPrice),
      volume: quote.volume + volumeChange,
      change: finalPrice - quote.openPrice,
      changePercent:
        ((finalPrice - quote.openPrice) / quote.openPrice) * 100,
      timestamp: new Date(gameNow),
    };

    this.quotes.set(symbol, updatedQuote);

    // 添加到历史记录（使用游戏时间）
    const history = this.history.get(symbol) ?? [];
    history.push({
      timestamp: new Date(gameNow),
      price: finalPrice,
      volume: volumeChange,
    });

    // 只保留最近1000条记录
    if (history.length > 1000) {
      history.shift();
    }
    this.history.set(symbol, history);
  }

  /**
   * 模拟交易成交（更新成交量和价格）
   */
  executeTrade(symbol: string, quantity: number, price: number): void {
    const quote = this.quotes.get(symbol);
    if (!quote) {
      return;
    }

    // 更新成交量和价格
    const updatedQuote: StockQuote = {
      ...quote,
      lastPrice: price,
      volume: quote.volume + quantity,
      timestamp: new Date(),
    };

    this.quotes.set(symbol, updatedQuote);

    // 添加到历史记录
    const history = this.history.get(symbol) ?? [];
    history.push({
      timestamp: new Date(),
      price: price,
      volume: quantity,
    });

    if (history.length > 1000) {
      history.shift();
    }
    this.history.set(symbol, history);
  }

  /**
   * 重置每日数据（开盘时调用）
   */
  resetDailyData(symbol: string): void {
    const quote = this.quotes.get(symbol);
    if (!quote) {
      return;
    }

    const updatedQuote: StockQuote = {
      ...quote,
      openPrice: quote.lastPrice,
      highPrice: quote.lastPrice,
      lowPrice: quote.lastPrice,
      volume: 0,
      change: 0,
      changePercent: 0,
      timestamp: new Date(),
    };

    this.quotes.set(symbol, updatedQuote);
  }
}

// 单例实例
let marketDataInstance: MarketDataService | null = null;

/**
 * 获取市场数据服务单例
 */
export function getMarketDataService(): MarketDataService {
  if (!marketDataInstance) {
    marketDataInstance = new MarketDataService();
  }
  return marketDataInstance;
}

/**
 * 重置市场数据服务（用于测试）
 */
export function resetMarketDataService(): MarketDataService {
  marketDataInstance = new MarketDataService();
  return marketDataInstance;
}




